package com.rolerealm.service.impl;

import com.rolerealm.service.LLMService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Service;

import java.net.URI;
import java.net.http.HttpClient;
import java.net.http.HttpRequest;
import java.net.http.HttpResponse;
import java.nio.charset.StandardCharsets;
import java.time.Duration;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Slf4j
@Service
@Primary
public class DeepSeekLLMServiceImpl implements LLMService {

    @Value("${llm.deepseek.apiKey:}")
    private String apiKey;

    @Value("${llm.deepseek.baseUrl:https://api.qnaigc.com}")
    private String baseUrl;

    @Value("${llm.deepseek.model:deepseek-v3}")
    private String defaultModel;

    @Value("${llm.deepseek.timeoutSeconds:30}")
    private int timeoutSeconds;

    private final HttpClient httpClient = HttpClient.newBuilder()
            .connectTimeout(Duration.ofSeconds(10))
            .build();

    @Override
    public String infer(String prompt, String languageOrModel) {
        if (apiKey == null || apiKey.isBlank()) {
            log.warn("DeepSeek API Key 未配置，回退到简单回声");
            return "AI回复：" + (prompt == null ? "" : prompt);
        }

        // 使用配置的模型，支持多种DeepSeek模型
        String model = (languageOrModel != null && !languageOrModel.isBlank()) ? languageOrModel : defaultModel;
        String url = baseUrl.endsWith("/") ? (baseUrl + "v1/chat/completions") : (baseUrl + "/v1/chat/completions");

        String body = "{\n" +
                "  \"model\": \"" + escape(model) + "\",\n" +
                "  \"messages\": [\n" +
                "    {\"role\": \"system\", \"content\": \"You are RoleRealm AI assistant, specialized in role-playing and character simulation. You excel at adopting different character personas including fictional characters (like Harry Potter, Conan), historical figures (like Socrates), and any other characters. When role-playing, you should: 1) Maintain the character's unique speaking style, vocabulary, and mannerisms; 2) Stay in character throughout the conversation; 3) Respond naturally and authentically as that character would; 4) Use appropriate tone and personality traits. You can also provide helpful information while staying in character.\"},\n" +
                "    {\"role\": \"user\", \"content\": " + toJsonString(prompt) + "}\n" +
                "  ],\n" +
                "  \"temperature\": 0.8,\n" +
                "  \"max_tokens\": 2000\n" +
                "}";

        HttpRequest request = HttpRequest.newBuilder()
                .uri(URI.create(url))
                .timeout(Duration.ofSeconds(Math.max(5, timeoutSeconds)))
                .header("Authorization", "Bearer " + apiKey)
                .header("Content-Type", "application/json")
                .POST(HttpRequest.BodyPublishers.ofString(body, StandardCharsets.UTF_8))
                .build();

        try {
            log.debug("调用DeepSeek API，模型: {}, URL: {}", model, url);
            HttpResponse<String> response = httpClient.send(request, HttpResponse.BodyHandlers.ofString());
            
            if (response.statusCode() == 200) {
                String responseBody = response.body();
                log.debug("DeepSeek API响应: {}", responseBody);
                
                // 解析响应
                String content = extractContentFromResponse(responseBody);
                if (content != null && !content.trim().isEmpty()) {
                    log.info("DeepSeek API调用成功，返回内容长度: {}", content.length());
                    return content;
                } else {
                    log.warn("DeepSeek API返回空内容，响应: {}", responseBody);
                    return "抱歉，我暂时无法回复您的消息。";
                }
            } else {
                log.error("DeepSeek API调用失败，状态码: {}, 响应: {}", response.statusCode(), response.body());
                return "抱歉，AI服务暂时不可用，请稍后重试。";
            }
        } catch (Exception e) {
            log.error("调用DeepSeek API异常", e);
            return "抱歉，AI服务出现异常，请稍后重试。";
        }
    }

    /**
     * 从API响应中提取内容
     */
    private String extractContentFromResponse(String responseBody) {
        try {
            // 简单的JSON解析，提取content字段
            Pattern pattern = Pattern.compile("\"content\"\\s*:\\s*\"([^\"]*(?:\\\\.[^\"]*)*)\"");
            Matcher matcher = pattern.matcher(responseBody);
            if (matcher.find()) {
                String content = matcher.group(1);
                // 处理转义字符
                content = content.replace("\\n", "\n")
                               .replace("\\t", "\t")
                               .replace("\\r", "\r")
                               .replace("\\\"", "\"")
                               .replace("\\\\", "\\");
                return content;
            }
        } catch (Exception e) {
            log.warn("解析DeepSeek API响应失败", e);
        }
        return null;
    }

    /**
     * 转义JSON字符串
     */
    private String toJsonString(String s) {
        if (s == null) return "null";
        return '"' + escape(s) + '"';
    }

    /**
     * 转义特殊字符
     */
    private String escape(String s) {
        return s.replace("\\", "\\\\")
                .replace("\"", "\\\"")
                .replace("\n", "\\n")
                .replace("\r", "\\r")
                .replace("\t", "\\t");
    }

}
